/**
 * @file    Matrix.h
 * @author  Han Yaoting
 * @date    Thu Oct 13 2023
 * 
 * @brief   Homework2 of D.S.A. "Define Matrix Class"
 */

#ifndef MATRIX_H
#define MATRIX_H

#include <vector>

/**
 * @class Matrix
 * @brief Matrix Class
 */

class Matrix {

private:

  int rows_;                   /**< Number of matrix rows */
  int cols_;                   /**< Number of matrix columns */
  std::vector<double> data_;   /**< Element data of matrix */

  /**
   * @brief   Gets the starting subscript of the specified row of the matrix
   * @param   row The row-th
   */
  int get_StartIndex(int row) const;

  /**
   * @brief   Calculate the adjoint matrix
   * @return  Adjoint matrix
   */
  Matrix calculate_AdjointMatrix() const;

  /**
   * @brief   Determine whether the matrix is a square matrix or not
   * @return  If the matrix is a square matrix, then return ture, else return false
   */
  bool is_SquareMatrix() const;

  /**
   * @brief   Calculate matrix determinant values when it is a square matrix
   * @return  Determinant values of matrix
   */
  double calculate_Determinant() const;

  /**
   * @brief   Calculate inverse matrix when it is a square matrix
   * @return  Inverse matrix
   */
  Matrix calculate_InverseMatrix() const;


public:

  /**
   * @brief   Construct function
   * @param   rows Number of matrix rows
   * @param   cols Number of matrix columns
   */
  Matrix(int rows, int cols);

  /**
   * @brief   Get the number of matrix rows
   */
  int get_Rows() const;

  /**
   * @brief   Get the number of matrix columns
   */
  int get_Cols() const;

  /**
   * @brief   Get the element of matrix
   * @param   row The row-th of the element
   * @param   col The column-th of the element
   */
  double get_Element(int row, int col) const;

  /**
   * @brief   Set the element of matrix
   * @param   row The row-th of the element
   * @param   col The column-th of the element
   * @param   value The value of the element
   */
  void set_Element(int row, int col, double value);

  /**
   * @brief   Addition of matirx
   * @param   other_Matrix Another matrix
   * @return  The result-matrix of addition
   */
  Matrix operator+(const Matrix& other_Matrix) const;

  /**
   * @brief   Scalar multiplication of matrix
   * @param   Scalar Coefficients over the field of real numbers
   * @return  The result-matrix of scalar multiplication
   */
  Matrix operator*(double Scalar) const;

  /**
   * @brief   Multiplication of matrix
   * @param   other_Matrix Another matrix
   * @return  The result-matrix of multiplication
   */
  Matrix operatorx(const Matrix& other_Matrix) const;

  /**
   * @brief The multiplication of matrix and vector
   * @param vector vector
   * @return The result-vector of multiplication
   */
  std::vector<double> operatorX(const std::vector<double>& vector) const;


};

#endif  // MATRIX_H